/*
 * Copyright 2010 Michael Nitsche
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package de.mnit.basis.swt.anw;

import de.mnit.basis.daten.typ.Klasse;
import de.mnit.basis.fehler.system.F_Sys_InOut;
import de.mnit.basis.swt.dialog.SWT_Fehler;
import de.mnit.basis.swt.element.steuer.rollbar.gruppe.bild.deko.SWT_Fenster;
import de.mnit.basis.swt.element.steuer.rollbar.gruppe.bild.deko.S_Fenster;
import de.mnit.basis.sys.event.S_Extern;
import de.mnit.basis.sys.event.S_Zuhoerer;


/**
 * @author Michael Nitsche
 * 16.06.2009	Shutdownhook wird nur gesetzt, wenn benötigt
 */
public abstract class A_MN_Anw<TA extends A_MN_Anw<TA>> extends A_MN_Fenster<TA> {

	private static final String E_BEREIT="BEREIT";
	private static final String E_ENDE="ENDE";

	private boolean shutdownhook=false;
	private S_Fenster<?> fenster;


	/**
	 * Geht nicht mit Webstart
	 */
	public static void start(Class<? extends A_MN_Anw<?>> start)   { start(start,(Object[])null); }

	/**
	 * Geht nicht mit Webstart
	 */
	public static void start(Class<? extends A_MN_Anw<?>> start, Object... parameter) {
		if(parameter==null) parameter=new Object[0];
		try {
			final A_MN_Anw<?> instanz= Klasse.nInstanz(start, parameter);
			((SWT_Fenster)instanz.fenster(instanz)).start(new S_Zuhoerer<Object>(){ //TODO Unbedingt mit A_MN_Fenster abgleichen und überdenken!!!!!
				public void verarbeite(Object o) {
					instanz.zuhoererStart(E_BEREIT, null);
				}
			});
		}
		catch(Throwable t)   { SWT_Fehler.zeig(t, true); }
	}

	public static void start(final A_MN_Anw<?> instanz) {
		try {
			((SWT_Fenster)instanz.fenster(instanz)).start(new S_Zuhoerer<Object>(){ //TODO Unbedingt mit A_MN_Fenster abgleichen und überdenken!!!!!
				public void verarbeite(Object o) {
					instanz.zuhoererStart(E_BEREIT, null);
				}
			});
		}
		catch(Throwable t)   { SWT_Fehler.zeig(t, true); }
	}

	/** Generell nicht verkehrt, aber wird momentan nie (durch die static-start) aufgerufen!!! Aktuell kein Bedarf **/
//	protected abstract void start(A_SWT_Fenster<?> fenster);


	/**
	 * Wird erst geworfen, wenn SWT schon Disposed ist!
	 * Nicht mit Webstart-Sicher!
	 */
	public void eEndeAnw(S_Zuhoerer<?> z) {
		if(!shutdownhook) {
			Runtime.getRuntime().addShutdownHook( new Thread(){
				public void run() {
					((TA)t).zuhoererStart(E_ENDE, null);
				}
			});
			shutdownhook=true;
		}
		this.zuhoererPlus(E_ENDE, z);
	}

	/**
	 * Wird geworfen, wenn das Hauptfenster der Anwendung geschlossen werden soll
	 * t.gDisplay().addListener(SWT.Close: Geht zwar, aber da sind die Fenster schon disposed!
	 */
	public void eEndeSWT(final S_Extern<?, Boolean> z) {
		t.endeFenster(this.gHauptfenster().swt(), z);
	}

	public S_Fenster<?> gHauptfenster() {
		return this.fenster;
	}

	protected abstract S_Fenster<?> hauptfenster(A_MN_Anw<?> instanz) throws F_Sys_InOut;

	protected final S_Fenster<?> fenster(A_MN_Gruppe<?> instanz) throws F_Sys_InOut {
		this.fenster=hauptfenster((A_MN_Anw<?>)instanz);
		return this.fenster;
	}

}
